<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
    <style>
        div{
            border: 1px solid transparent;
        }
    </style>
</head>
<body>
     <div id="app">
        <div v-color:text.a.b.c="colorStr">123123123</div>
        <div v-color:border.a.b.c="colorStr">123123123</div>
        <div v-color:bg.a.b.c="colorStr">123123123</div>
        <br>
        <button @click="changeColor">改变颜色</button>
     </div>

</body>
<script>
    // vue 指令
    // 指令 (Directives) 是带有 v- 前缀的特殊 attribute。指令 attribute 的值预期是单个 JavaScript 表达式 (v-for 是例外情况，稍后我们再讨论)。指令的职责是，当表达式的值改变时，将其产生的连带影响，响应式地作用于 DOM。

    // 常见格式
    // v-指令名 = "指令值"        v-if  v-show
    // v-指令名:参数 = = "指令值"     v-bind:class v-on:click
    // v-指令名:参数.修饰符.修饰符.修饰符 = = "指令值"     v-on:click.stop   v-on:submit.prevent   v-model.lazy

    // 自定义指令

    // 全局自定义指令  => 定义一次所有的组件均可以使用

    // 指令相关的钩子函数
    // 一个指令定义对象可以提供如下几个钩子函数 (均为可选)：
    // bind：只调用一次，指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
    // inserted：被绑定元素插入父节点时调用 (仅保证父节点存在，但不一定已被插入文档中)。
    // update：所在组件的 VNode 更新时调用，但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变，也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)

    // componentUpdated：指令所在组件的 VNode 及其子 VNode 全部更新后调用。
    // unbind：只调用一次，指令与元素解绑时调用。

    // 钩子函数相关的参数
    // el 指令所绑定的元素，可以用来直接操作 DOM。
    // binding  => 一个对象，包含指令相关数据(指令名 指令值 指令表达式  参数  修饰符(可以有多个) )以下 property
    //     name：指令名，不包括 v- 前缀。
    //     value：指令的绑定值，例如：v-my-directive="1 + 1" 中，绑定值为 2。
    //     oldValue：指令绑定的前一个值，仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
    //     expression：字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中，表达式为 "1 + 1"。
    //     arg：传给指令的参数，可选。例如 v-my-directive:foo 中，参数为 "foo"。
    //     modifiers：一个包含修饰符的对象。例如：v-my-directive.foo.bar 中，修饰符对象为 { foo: true, bar: true }。

    // v-color   => 插入父元素时执行一次, 数据更新时再次执行
    // Vue.directive("color",{
    //     inserted:function(el,binding){
    //         console.log("el",el);
    //         console.log("binding",binding);
    //         let {value,arg="text"} = binding;

    //         switch(arg){
    //             case "text":el.style.color=value; break;
    //             case "bg":el.style.backgroundColor=value; break;
    //             case "border":el.style.borderColor=value; break;
    //         }
    //     },
    //     update:function(el,binding){
    //         console.log("el",el);
    //         console.log("binding",binding);
    //         let {value,arg="text"} = binding;

    //         switch(arg){
    //             case "text":el.style.color=value; break;
    //             case "bg":el.style.backgroundColor=value; break;
    //             case "border":el.style.borderColor=value; break;
    //         }
    //     },
    // })


    //  v-color   => 插入父元素时执行一次, 数据更新时再次执行

    Vue.directive("color",function(el,binding){
        console.log("el",el);
        console.log("binding",binding);
        let {value,arg="text"} = binding;

        switch(arg){
            case "text":el.style.color=value; break;
            case "bg":el.style.backgroundColor=value; break;
            case "border":el.style.borderColor=value; break;
        }
    })


    var vm = new Vue({
        el:"#app",
        data:{
            colorStr:"red",
        },
        methods: {
            changeColor(){
                this.colorStr = "blue";
            }
        },
    })


</script>
</html>